package main

import (
	"fmt"
)

//高阶函数
//函数作为函数的参数，传递给另一个函数，可以作为另一个函数的返回值
//函数作为参数
// func sayHello(name string) {
// 	fmt.Printf("Hello,%s", name)
// }
// func f1(name string, f func(string)) {
// 	f(name)
// }
// func main() {
// 	f1("skye", sayHello)
// }
//函数作为返回值
// func add(x, y int) int {
// 	return x + y
// }
// func sub(x, y int) int {
// 	return x - y
// }
// func cal(s string) func(int, int) int {
// 	switch s {
// 	case "+":
// 		return add
// 	case "-":
// 		return sub
// 	default:
// 		return nil
// 	}
// }
// func main() {
// 	add := cal("+")
// 	r := add(1, 3)
// 	fmt.Printf("r: %v\n", r)

// 	fmt.Println("----------")
// 	sub := cal("-")
// 	s := sub(5, 2)
// 	fmt.Printf("s: %v\n", s)
// }

//匿名函数
//函数不能嵌套，但函数内部可以定义匿名函数 - 没有名称的函数 - 既没有参数也没有返回值
// func main() {
// 	max := func(a int, b int) int {
// 		if a > b {
// 			return a
// 		} else {
// 			return b
// 		}
// 	}
// 	i := max(5, 7)
// 	fmt.Printf("i: %v\n", i)
// }
//自己执行
// func main() {
// 	func(a int, b int) {
// 		max := 0
// 		if a > b {
// 			max = a
// 		} else {
// 			max = b
// 		}
// 		fmt.Printf("max: %v\n", max)
// 	}(1, 2)
// }

//闭包 = 函数+引用环境
//定义在一个函数内部的函数
//本质上：将函数内部与外部连接起来的桥梁
// func add() func(int) int {
// 	var x int
// 	return func(y int) int {
// 		x += y
// 		return x
// 	}
// }
// //变量f是一个函数并且它引用了其外部作用域中的x变量，
// //此时f就是一个闭包。
// //在f的生命周期内，变量x也一直有效。
// func main() {
// 	var f = add()
// 	fmt.Println(f(10)) //10
// 	fmt.Println(f(20)) //30
// 	fmt.Println(f(30)) //60
// 	fmt.Println(f(40)) //100
// 	fmt.Println("---------")
// 	f1 := add()
// 	fmt.Println(f1(100)) //100
// 	fmt.Println(f1(200)) //300
// }

// 闭包进阶
// func makeSuffixFunc(suffix string) func(string) string {
// 	return func(name string) string {
// 		if !strings.HasSuffix(name, suffix) {
// 			return name + suffix
// 		}
// 		return name
// 	}
// }
// func main() {
// 	jpgFunc := makeSuffixFunc(".jpg")
// 	txtFunc := makeSuffixFunc(".txt")
// 	fmt.Println(jpgFunc("test"))
// 	fmt.Println(txtFunc("test"))
// }

// func calc(base int) (func(int) int, func(int) int) {
// 	add := func(i int) int {
// 		base += i
// 		return base
// 	}

// 	sub := func(i int) int {
// 		base -= i
// 		return base
// 	}
// 	return add, sub
// }

// func main() {
// 	f1, f2 := calc(10)
// 	fmt.Println(f1(1), f2(2))
// 	fmt.Println(f1(3), f2(4))
// 	fmt.Println(f1(5), f2(6))
// }

// 递归 - 函数自身调用自己
// 1.设定退出条件 2.栈溢出
//
//	func a(n int) int {
//		if n == 1 {
//			return 1 //返回条件
//		} else {
//			return n * a(n-1)
//		}
//	}
//
//	func main() {
//		n := 5
//		r := a(n)
//		fmt.Printf("r: %v\n", r)
//	}
//
// 斐波那契数列
// f(n)=f(n-1)+f(n-2)且f(2)=f(1)=1
// func f(n int) int {
// 	if n == 1 || n == 2 { //退出点判断
// 		return 1
// 	}
// 	return f(n-1) + f(n-2)
// }
// func main() {
// 	r := f(5)
// 	fmt.Printf("r: %v\n", r)
// }

// defer语句 - 压入栈中 -资源清理
// 延迟处理 - 先进后出
// func main() {
// 	fmt.Println("start")
// 	defer fmt.Println("step1")
// 	defer fmt.Println("step2")
// 	defer fmt.Println("step3")
// 	fmt.Println("end")
// } //start end 3 2 1

// init函数 - 先于mian - 初始化操作
// 可以有多个init函数
// 顺序： 变量初始化 -> init() -> main()
var a int = initVar()

func init() {
	fmt.Println("init2")
}
func init() {
	fmt.Println("init")
}
func initVar() int {
	fmt.Println("init var...")
	return 100
}
func main() {
	fmt.Println("main...")
}
